package com.zliuyno.rpcdemo.transport;

import com.zliuyno.io.testreactor.netty.SerDerUtil;
import com.zliuyno.rpcdemo.util.Packmsg;
import com.zliuyno.rpcdemo.rpc.Dispatcher;
import com.zliuyno.rpcdemo.rpc.Protocol.MyContent;
import com.zliuyno.rpcdemo.rpc.Protocol.MyHeader;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ServerRequestHandler extends ChannelInboundHandlerAdapter {
    Dispatcher dis = null;

    public ServerRequestHandler(Dispatcher dis) {
        this.dis = dis;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {


//        System.out.println("server handler:" + requestPkg.content.getArgs()[0]);

        //如果处理完了 需要给客户端返回
        //返回数据需要封装为一个bytebuf    因为是RPC,你得有requestID
        //在client一侧需要解决编码问题

        //有新的header+content
        String ioThreadName = Thread.currentThread().getName();
        //1.直接在当前方法处理IO 业务和处理返回的事
        //2.使用netty自己的eventloop来处理业务及返回
//        ctx.executor().execute(new Runnable() {
        ctx.executor().parent().execute(new Runnable() {
            @Override
            public void run() {

                Packmsg requestPkg = (Packmsg) msg;

                Object res = null;
                String serviceName = requestPkg.getContent().getName();
                String methodName = requestPkg.getContent().getMethodName();
                Object c = dis.get(serviceName);
                Class<?> clazz = c.getClass();
                Method method = null;
                try {
                    method = clazz.getMethod(methodName, requestPkg.getContent().getParameterTypes());
                    res = method.invoke(c, requestPkg.getContent().getArgs());
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                String execThreadName = Thread.currentThread().getName();

                MyContent content = new MyContent();
//                String s = "io thread : " + ioThreadName + "; exec thread :" + execThreadName + "; from args - " + requestPkg.content.getArgs()[0];

//                System.out.println(s);
                content.setRes((String) res);
                byte[] contentByte = SerDerUtil.ser(content);
//                System.out.println("22222222222222222222 :"+contentByte.length);

                MyHeader header = new MyHeader();
                header.setRequestID(requestPkg.getHeader().getRequestID());
                header.setFlag(0x14141424);
                header.setDataLen(contentByte.length);

                byte[] headerByte = SerDerUtil.ser(header);

                ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(headerByte.length + contentByte.length);

                byteBuf.writeBytes(headerByte);
                byteBuf.writeBytes(contentByte);
                ctx.writeAndFlush(byteBuf);


            }
        });
    }
}